package com.lx.zxs.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.lx.zxs.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpSession;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author 2018年5月18日16:11:48
 */
@Component
@ServerEndpoint(value = "/user/websocket/{id}")
public class WebSocket {

    @Autowired
    private UserService userService;

    private static WebSocket  webSocket ;  //  关键点1   静态初使化 一个工具类  这样是为了在spring初使化之前

    public void setUserService(UserService  userService) {
        this.userService = userService;
    }

    @PostConstruct     //关键二   通过@PostConstruct 和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作
    public void init() {
        webSocket = this;
        webSocket.userService = this.userService;   // 初使化时将已静态化的testService实例化
    }
    private Logger logger =  LoggerFactory.getLogger(this.getClass());
    /**
     * 在线人数
     */
    public static int onlineNumber = 0;
    /**
     * 以用户的姓名为key，WebSocket为对象保存起来
     */
    private static Map<String, WebSocket> clients = new ConcurrentHashMap<String, WebSocket>();
    /**
     * 会话
     */
    private Session session;
    /**
     * 用户名称
     */
    private String id;
    /**
     * 建立连接
     *
     * @param session
     */
    @OnOpen
    public void onOpen(@PathParam("id") String id, Session session)
    {
        onlineNumber++;
//        logger.info("现在来连接的客户id："+session.getId()+"用户名："+id);
        this.id = id;

        this.session = session;
//        logger.info("有新连接加入！ 当前在线人数" + onlineNumber);
        //把自己的信息加入到map当中去
        clients.put(id, this);
    }

    @OnError
    public void onError(Session session, Throwable error) {
        logger.info("服务端发生了错误"+error.getMessage());
        //error.printStackTrace();
    }
    /**
     * 连接关闭
     */
    @OnClose
    public void onClose(Session session)
    {
        onlineNumber--;
        //webSockets.remove(this);
        clients.remove(id+"");
        try {
            //messageType 1代表上线 2代表下线 3代表在线名单  4代表普通消息
            Map<String,Object> map1 = Maps.newHashMap();
            map1.put("messageType",2);
            map1.put("onlineUsers",clients.keySet());
            map1.put("username",id);
            sendMessageAll(JSON.toJSONString(map1),id);
        }
        catch (IOException e){
            logger.info(id+"下线的时候通知所有人发生了错误");
        }
        logger.info("有连接关闭！");
//        logger.info("有连接关闭！ 当前在线人数" + onlineNumber);
    }

    /**
     * 收到客户端的消息
     *
     * @param message 消息
     * @param session 会话
     */
    @OnMessage
    public void onMessage(String message, Session session){

        try {
            logger.info("来自客户端消息：" + message+"客户端的id是："+session.getId());
            JSONObject jsonObject = JSON.parseObject(message);
            JSONObject body = jsonObject.getJSONObject("body");

            String content = body.getString("content");
            String lid = body.getString("lid");
            String uid = body.getString("uid");
            String type = body.getString("type");
            String ctime = body.getString("ctime");
            String linkName = body.getString("linkName");
            //linkman需要查一下


            Map map = webSocket.userService.addChatData(Integer.parseInt(lid), Integer.parseInt(uid), 1, Integer.parseInt(type), content, ctime, linkName);

            webSocket.userService.updateContactsStatus(0,(String) map.get("uuid"));
            for (WebSocket item : clients.values()) {
                if (item.id.equals(lid) ) {
                    webSocket.userService.updateContactsStatus(1,(String) map.get("uuid"));
                    item.session.getAsyncRemote().sendText(JSONObject.toJSONString(map));
                    System.out.println(lid+"向"+uid+"发送了消息");
                    break;
                }
            }

        }
        catch (Exception e){
            e.printStackTrace();
            logger.info("发生了错误了");

        }

    }


    public void sendMessageTo(String message, String lid) throws IOException {
        for (WebSocket item : clients.values()) {
            if (item.id.equals(lid) ) {
                item.session.getAsyncRemote().sendText(message);
                break;
            }
        }
    }

    public void sendMessageAll(String message,String FromUserName) throws IOException {
        for (WebSocket item : clients.values()) {
            item.session.getAsyncRemote().sendText(message);
        }
    }

    public static synchronized int getOnlineCount() {
        return onlineNumber;
    }

}